﻿//rumsey modified single var encryptor, use Crypto.Encryt(string) and Crypto.Decrypt(string)
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace ShadowEraDeckEditor
{
public class Crypto
{
    /// <summary>
    /// Encrypts specified plaintext using Rijndael symmetric key algorithm
    /// and returns a base64-encoded result.
    /// </summary>
    /// <param name="plainText">
    /// Plaintext value to be encrypted.
    /// </param>
    /// <param name="passPhrase">
    /// Passphrase from which a pseudo-random password will be derived. The
    /// derived password will be used to generate the encryption key.
    /// Passphrase can be any string. In this example we assume that this
    /// passphrase is an ASCII string.
    /// </param>
    /// <param name="saltValue">
    /// Salt value used along with passphrase to generate password. Salt can
    /// be any string. In this example we assume that salt is an ASCII string.
    /// </param>
    /// <param name="hashAlgorithm">
    /// Hash algorithm used to generate password. Allowed values are: "MD5" and
    /// "SHA1". SHA1 hashes are a bit slower, but more secure than MD5 hashes.
    /// </param>
    /// <param name="passwordIterations">
    /// Number of iterations used to generate password. One or two iterations
    /// should be enough.
    /// </param>
    /// <param name="initVector">
    /// Initialization vector (or IV). This value is required to encrypt the
    /// first block of plaintext data. For RijndaelManaged class IV must be 
    /// exactly 16 ASCII characters long.
    /// </param>
    /// <param name="keySize">
    /// Size of encryption key in bits. Allowed values are: 128, 192, and 256. 
    /// Longer keys are more secure than shorter keys.
    /// </param>
    /// <returns>
    /// Encrypted value formatted as a base64-encoded string.
    /// </returns>
    /// 
    //string plainText = "Hello, World!";    // original plaintext

    public static string Encrypt(string   plainText)
    {
        string passPhrase = "Pas5pr@se123456789";        // can be any string
        string saltValue = "s@1tValue";        // can be any string
        string hashAlgorithm = "SHA1";             // can be "MD5"
        int passwordIterations = 2;                  // can be any number
        string initVector = "@1B2c3D4e5F6g7H8"; // must be 16 bytes
        int keySize = 256;                // can be 192 or 128
        // Convert strings into byte arrays.
        // Let us assume that strings only contain ASCII codes.
        // If strings include Unicode characters, use Unicode, UTF7, or UTF8 
        // encoding.
        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] saltValueBytes  = Encoding.ASCII.GetBytes(saltValue);
        
        // Convert our plaintext into a byte array.
        // Let us assume that plaintext contains UTF8-encoded characters.
        byte[] plainTextBytes  = Encoding.UTF8.GetBytes(plainText);
        
        // First, we must create a password, from which the key will be derived.
        // This password will be generated from the specified passphrase and 
        // salt value. The password will be created using the specified hash 
        // algorithm. Password creation can be done in several iterations.
        PasswordDeriveBytes password = new PasswordDeriveBytes(
                                                        passPhrase, 
                                                        saltValueBytes, 
                                                        hashAlgorithm, 
                                                        passwordIterations);
        
        // Use the password to generate pseudo-random bytes for the encryption
        // key. Specify the size of the key in bytes (instead of bits).
        byte[] keyBytes = password.GetBytes(keySize / 8);
        
        // Create uninitialized Rijndael encryption object.
        RijndaelManaged symmetricKey = new RijndaelManaged();
        
        // It is reasonable to set encryption mode to Cipher Block Chaining
        // (CBC). Use default options for other symmetric key parameters.
        symmetricKey.Mode = CipherMode.CBC;        
        
        // Generate encryptor from the existing key bytes and initialization 
        // vector. Key size will be defined based on the number of the key 
        // bytes.
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
                                                         keyBytes, 
                                                         initVectorBytes);
        
        // Define memory stream which will be used to hold encrypted data.
        MemoryStream memoryStream = new MemoryStream();        
                
        // Define cryptographic stream (always use Write mode for encryption).
        CryptoStream cryptoStream = new CryptoStream(memoryStream, 
                                                     encryptor,
                                                     CryptoStreamMode.Write);
        // Start encrypting.
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                
        // Finish encrypting.
        cryptoStream.FlushFinalBlock();

        // Convert our encrypted data from a memory stream into a byte array.
        byte[] cipherTextBytes = memoryStream.ToArray();
                
        // Close both streams.
        memoryStream.Close();
        cryptoStream.Close();
        
        // Convert encrypted data into a base64-encoded string.
        string cipherText = Convert.ToBase64String(cipherTextBytes);
        
        // Return encrypted string.
        return cipherText;
    }
    
    /// <summary>
    /// Decrypts specified ciphertext using Rijndael symmetric key algorithm.
    /// </summary>
    /// <param name="cipherText">
    /// Base64-formatted ciphertext value.
    /// </param>
    /// <param name="passPhrase">
    /// Passphrase from which a pseudo-random password will be derived. The
    /// derived password will be used to generate the encryption key.
    /// Passphrase can be any string. In this example we assume that this
    /// passphrase is an ASCII string.
    /// </param>
    /// <param name="saltValue">
    /// Salt value used along with passphrase to generate password. Salt can
    /// be any string. In this example we assume that salt is an ASCII string.
    /// </param>
    /// <param name="hashAlgorithm">
    /// Hash algorithm used to generate password. Allowed values are: "MD5" and
    /// "SHA1". SHA1 hashes are a bit slower, but more secure than MD5 hashes.
    /// </param>
    /// <param name="passwordIterations">
    /// Number of iterations used to generate password. One or two iterations
    /// should be enough.
    /// </param>
    /// <param name="initVector">
    /// Initialization vector (or IV). This value is required to encrypt the
    /// first block of plaintext data. For RijndaelManaged class IV must be
    /// exactly 16 ASCII characters long.
    /// </param>
    /// <param name="keySize">
    /// Size of encryption key in bits. Allowed values are: 128, 192, and 256.
    /// Longer keys are more secure than shorter keys.
    /// </param>
    /// <returns>
    /// Decrypted string value.
    /// </returns>
    /// <remarks>
    /// Most of the logic in this function is similar to the Encrypt
    /// logic. In order for decryption to work, all parameters of this function
    /// - except cipherText value - must match the corresponding parameters of
    /// the Encrypt function which was called to generate the
    /// ciphertext.
    /// </remarks>
    public static string Decrypt(string   cipherText)
    {
        string passPhrase = "Pas5pr@se123456789";        // can be any string
        string saltValue = "s@1tValue";        // can be any string
        string hashAlgorithm = "SHA1";             // can be "MD5"
        int passwordIterations = 2;                  // can be any number
        string initVector = "@1B2c3D4e5F6g7H8"; // must be 16 bytes
        int keySize = 256;                // can be 192 or 128
        // Convert strings defining encryption key characteristics into byte
        // arrays. Let us assume that strings only contain ASCII codes.
        // If strings include Unicode characters, use Unicode, UTF7, or UTF8
        // encoding.
        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] saltValueBytes  = Encoding.ASCII.GetBytes(saltValue);
        
        // Convert our ciphertext into a byte array.
        byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
        
        // First, we must create a password, from which the key will be 
        // derived. This password will be generated from the specified 
        // passphrase and salt value. The password will be created using
        // the specified hash algorithm. Password creation can be done in
        // several iterations.
        PasswordDeriveBytes password = new PasswordDeriveBytes(
                                                        passPhrase, 
                                                        saltValueBytes, 
                                                        hashAlgorithm, 
                                                        passwordIterations);
        
        // Use the password to generate pseudo-random bytes for the encryption
        // key. Specify the size of the key in bytes (instead of bits).
        byte[] keyBytes = password.GetBytes(keySize / 8);
        
        // Create uninitialized Rijndael encryption object.
        RijndaelManaged    symmetricKey = new RijndaelManaged();
        
        // It is reasonable to set encryption mode to Cipher Block Chaining
        // (CBC). Use default options for other symmetric key parameters.
        symmetricKey.Mode = CipherMode.CBC;
        
        // Generate decryptor from the existing key bytes and initialization 
        // vector. Key size will be defined based on the number of the key 
        // bytes.
        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(
                                                         keyBytes, 
                                                         initVectorBytes);
        
        // Define memory stream which will be used to hold encrypted data.
        MemoryStream  memoryStream = new MemoryStream(cipherTextBytes);
                
        // Define cryptographic stream (always use Read mode for encryption).
        CryptoStream  cryptoStream = new CryptoStream(memoryStream, 
                                                      decryptor,
                                                      CryptoStreamMode.Read);

        // Since at this point we don't know what the size of decrypted data
        // will be, allocate the buffer long enough to hold ciphertext;
        // plaintext is never longer than ciphertext.
        byte[] plainTextBytes = new byte[cipherTextBytes.Length];
        
        // Start decrypting.
        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 
                                                   0, 
                                                   plainTextBytes.Length);
                
        // Close both streams.
        memoryStream.Close();
        cryptoStream.Close();
        
        // Convert decrypted data into a string. 
        // Let us assume that the original plaintext string was UTF8-encoded.
        string plainText = Encoding.UTF8.GetString(plainTextBytes, 
                                                   0, 
                                                   decryptedByteCount);
        
        // Return decrypted string.   
        return plainText;
    }

    public static string SEDecrypt(string s)
    {
        Encoding encoding;
        byte[] buffer;
        byte[] buffer2;
        string str;
        RijndaelManaged managed;
        MemoryStream stream;
        ICryptoTransform transform;
        CryptoStream stream2;
        StreamReader reader;
        encoding = Encoding.UTF8;
        buffer = encoding.GetBytes("07B6FE8F2EADF2D0BC68BC2AEE800B0A");
        buffer2 = encoding.GetBytes("C224913B2D914D7D");
        managed = new RijndaelManaged();
        //managed.Mode = 2;
        //managed.Padding = 3;
        managed.Mode = CipherMode.ECB;
        managed.Padding = PaddingMode.None;
    Label_0035:
        try
        {
            stream = new MemoryStream(Convert.FromBase64String(s));
        Label_0042:
            try
            {
                transform = managed.CreateDecryptor(buffer, buffer2);
            Label_004D:
                try
                {
                    stream2 = new CryptoStream(stream, transform, 0);
                Label_0059:
                    try
                    {
                        reader = new StreamReader(stream2);
                    Label_0062:
                        try
                        {
                            str = reader.ReadToEnd();
                            goto Label_007E;
                        }
                        finally
                        {
                        Label_006F:
                            if (reader == null)
                            {
                                goto Label_007D;
                            }
                            reader.Dispose();
                        Label_007D: ;
                        }
                    Label_007E:
                        goto Label_0092;
                    }
                    finally
                    {
                    Label_0083:
                        if (stream2 == null)
                        {
                            goto Label_0091;
                        }
                        stream2.Dispose();
                    Label_0091: ;
                    }
                Label_0092:
                    goto Label_00A6;
                }
                finally
                {
                Label_0097:
                    if (transform == null)
                    {
                        goto Label_00A5;
                    }
                    transform.Dispose();
                Label_00A5: ;
                }
            Label_00A6:
                goto Label_00BA;
            }
            finally
            {
            Label_00AB:
                if (stream == null)
                {
                    goto Label_00B9;
                }
                stream.Dispose();
            Label_00B9: ;
            }
        Label_00BA:
            goto Label_00DB;
        }
        catch (Exception)
        {
        Label_00BF:
            str = "Not a valid packet!!!";
            //Debug.Log("*** BAD RESPONSE " + s);
            goto Label_00DB;
        }
    Label_00DB:
        managed.Clear();
        return str;
    }
}

/// <summary>
/// Illustrates the use of RijndaelSimple class to encrypt and decrypt data.
/// </summary>
/*public class RijndaelSimpleTest
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        string   plainText          = "Hello, World!";    // original plaintext
        
        string   passPhrase         = "Pas5pr@se";        // can be any string
        string   saltValue          = "s@1tValue";        // can be any string
        string   hashAlgorithm      = "SHA1";             // can be "MD5"
        int      passwordIterations = 2;                  // can be any number
        string   initVector         = "@1B2c3D4e5F6g7H8"; // must be 16 bytes
        int      keySize            = 256;                // can be 192 or 128
        
        Console.WriteLine(String.Format("Plaintext : {0}", plainText));

        string  cipherText = Crypto.Encrypt(plainText);

        Console.WriteLine(String.Format("Encrypted : {0}", cipherText));
        
        plainText          = Crypto.Decrypt(cipherText);

        Console.WriteLine(String.Format("Decrypted : {0}", plainText));
    }
}
//
// END OF FILE
///////////////////////////////////////////////////////////////////////////////



    /*class Crypto
    {
    }*/
}

///////////////////////////////////////////////////////////////////////////////
// SAMPLE: Symmetric key encryption and decryption using Rijndael algorithm.
// 
// To run this sample, create a new Visual C# project using the Console
// Application template and replace the contents of the Class1.cs file with
// the code below.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// 
// Copyright (C) 2002 Obviex(TM). All rights reserved.
// 

/// <summary>
/// This class uses a symmetric key algorithm (Rijndael/AES) to encrypt and 
/// decrypt data. As long as encryption and decryption routines use the same
/// parameters to generate the keys, the keys are guaranteed to be the same.
/// The class uses static functions with duplicate code to make it easier to
/// demonstrate encryption and decryption logic. In a real-life application, 
/// this may not be the most efficient way of handling encryption, so - as
/// soon as you feel comfortable with it - you may want to redesign this class.
/// </summary>